package pe.edu.unmsm.fisi.ceups.servicio.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import org.hibernate.Session;
import pe.edu.unmsm.fisi.ceups.modelo.dao.GenericoDAO;
import pe.edu.unmsm.fisi.ceups.modelo.dao.hibernate.HibernateDAO;
import pe.edu.unmsm.fisi.ceups.modelo.dao.hibernate.utilitario.HibernateUtil;
import pe.edu.unmsm.fisi.ceups.modelo.entidad.Algoritmograsp;
import pe.edu.unmsm.fisi.ceups.modelo.entidad.Ccurso;
import pe.edu.unmsm.fisi.ceups.modelo.entidad.CcursoAperturado;
import pe.edu.unmsm.fisi.ceups.modelo.entidad.CcursoNoaperturado;
import pe.edu.unmsm.fisi.ceups.modelo.entidad.Ccursodocente;
import pe.edu.unmsm.fisi.ceups.modelo.entidad.Cdocente;
import pe.edu.unmsm.fisi.ceups.modelo.entidad.ChorarioDetalle;
import pe.edu.unmsm.fisi.ceups.modelo.entidad.ChorarioDisponibilidad;
import pe.edu.unmsm.fisi.ceups.modelo.entidad.ChorarioLaboratorio;
import pe.edu.unmsm.fisi.ceups.modelo.entidad.Cpersona;
import pe.edu.unmsm.fisi.ceups.servicio.ServicioProgramarCurso;

public class ImplProgramarCurso implements ServicioProgramarCurso {

    public List<Ccurso> test() {
        List<Ccurso> cCursos = null;
        Session session = HibernateUtil.getSessionFactory().openSession();
        try {
            session.beginTransaction();
            GenericoDAO<Ccurso> cCursoDAO = new HibernateDAO<Ccurso>(Ccurso.class, session);
            //cCursos = cCursoDAO.findAll();
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        } finally {
            session.close();
        }
        return cCursos;
    }

    public List<String[]> mostrar_cursosNoaperturados() {

        List<CcursoNoaperturado> cCursosNoaperturados = null;
        Session session = HibernateUtil.getSessionFactory().openSession();
        List<String[]> cCursoNoaperturado = new ArrayList<String[]>();


        try {
            session.beginTransaction();
            GenericoDAO<CcursoNoaperturado> cCursoNoaperturadoDAO = new HibernateDAO<CcursoNoaperturado>(CcursoNoaperturado.class, session);
            cCursosNoaperturados = cCursoNoaperturadoDAO.findByProperty("nropreinscritos", 9, ">=", "");

            for (int i = 0; i < cCursosNoaperturados.size(); i++) {


                String[] a = new String[2];
                a[0] = cCursosNoaperturados.get(i).getCcurso().getNombrecurso();
                a[1] = cCursosNoaperturados.get(i).getCcurso().getCodcurso();

                cCursoNoaperturado.add(a);

            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        } finally {
            session.close();
        }
        return cCursoNoaperturado;

    }

    public List<String[]> mostrar_docentes() {

        Session session = HibernateUtil.getSessionFactory().openSession();

        List<Cdocente> cDocentes = null;
        List<String[]> cPersonas = new ArrayList<String[]>();

        try {
            session.beginTransaction();
            GenericoDAO<Cdocente> cDocenteDAO = new HibernateDAO<Cdocente>(Cdocente.class, session);
            cDocentes = cDocenteDAO.findAll("");

            System.out.println("tamaño:" + cDocentes.size());

            for (int i = 0; i < cDocentes.size(); i++) {


                String[] a = new String[2];
                a[0] = cDocentes.get(i).getCpersona().getNombres() + cDocentes.get(i).getCpersona().getAppaterno();
                a[1] = (String) cDocentes.get(i).getIddocente().toString();

                cPersonas.add(a);

            }
            session.getTransaction().commit();

        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        } finally {

            session.close();
        }

        return cPersonas;

    }

    public List<String[]> mostrar_docentesxcurso(int idcurso) {

        Session session = HibernateUtil.getSessionFactory().openSession();

        List<Ccursodocente> cCursoDocentes = null;
        List<String[]> cPersonas = new ArrayList<String[]>();

        try {
            session.beginTransaction();
            GenericoDAO<Ccursodocente> cCursoDocenteDAO = new HibernateDAO<Ccursodocente>(Ccursodocente.class, session);
            cCursoDocentes = cCursoDocenteDAO.findByProperty("ccurso", idcurso, "=", " ");

            System.out.println("tamaño:" + cCursoDocentes.size());

            for (int i = 0; i < cCursoDocentes.size(); i++) {

                String[] a = new String[3];
                a[0] = cCursoDocentes.get(i).getCdocente().getCpersona().getNombres() + cCursoDocentes.get(i).getCdocente().getCpersona().getAppaterno() + cCursoDocentes.get(i).getCdocente().getCpersona().getApmaterno();
                a[1] = cCursoDocentes.get(i).getCdocente().getIddocente().toString();

                cPersonas.add(a);

            }

            session.getTransaction().commit();

        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        } finally {

            session.close();
        }

        return cPersonas;

    }

    public List<String[]> buscarCurso(String estado_curso, Integer numero_preinscritos) {
        List<String[]> cursos = new ArrayList<String[]>();
        Session session = HibernateUtil.getSessionFactory().openSession();
        try {
            session.beginTransaction();
            if (estado_curso.equals("1")) {
                GenericoDAO<CcursoNoaperturado> ccursoNoaperturadoDAO =
                        new HibernateDAO<CcursoNoaperturado>(CcursoNoaperturado.class, session);
                List<CcursoNoaperturado> ccursosNoaperturado = ccursoNoaperturadoDAO.findByProperty("nropreinscritos", numero_preinscritos, ">=", " ");
                for (CcursoNoaperturado ccursoNoaperturado : ccursosNoaperturado) {
                    String[] curso = new String[3];
                    curso[0] = ccursoNoaperturado.getCcurso().getCodcurso() +
                            "-" + ccursoNoaperturado.getIdcursonoaperturado();
                    curso[1] = ccursoNoaperturado.getCcurso().getNombrecurso();
                    curso[2] = "" + ccursoNoaperturado.getNropreinscritos();
                    cursos.add(curso);
                }
            } else if (estado_curso.equals("0")) {
                GenericoDAO<CcursoAperturado> ccursoAperturadoDAO =
                        new HibernateDAO<CcursoAperturado>(CcursoAperturado.class, session);
                List<CcursoAperturado> ccursosAperturado = ccursoAperturadoDAO.findAll("");
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy");
                for (CcursoAperturado ccursoAperturado : ccursosAperturado) {
                    String[] curso = new String[4];
                    curso[0] = ccursoAperturado.getCcurso().getCodcurso() +
                            "-" + ccursoAperturado.getIdcursoaperturado();
                    curso[1] = ccursoAperturado.getCcurso().getNombrecurso();
                    curso[2] = simpleDateFormat.format(ccursoAperturado.getFechainicio());
                    curso[3] = "" + ccursoAperturado.getNroinscritos();
                    cursos.add(curso);
                }
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        } finally {
            session.close();
        }
        return cursos;
    }

    
    
    
    
    
    public List<Integer[]> obtener_horario_docente(int iddocente) {


        Session session = HibernateUtil.getSessionFactory().openSession();
        List<Integer[]> horario = new ArrayList<Integer[]>();


        List<ChorarioDetalle> cHorarioDetalle = new ArrayList<ChorarioDetalle>();
        List<ChorarioDisponibilidad> cHorarios = null;

        try {
            session.beginTransaction();
            GenericoDAO<ChorarioDisponibilidad> cHorarioDAO = new HibernateDAO<ChorarioDisponibilidad>(ChorarioDisponibilidad.class, session);
            cHorarios = cHorarioDAO.findByProperty("cdocente", iddocente, "=", " ");


            for (int i = 0; i < cHorarios.size(); i++) {

                cHorarioDetalle = new ArrayList(cHorarios.get(i).getChorario().getChorarioDetalles());

            }
            for (int j = 0; j < cHorarioDetalle.size(); j++) {

                Integer[] a = new Integer[3];
                a[0] = cHorarioDetalle.get(j).getDia();
                a[1] = cHorarioDetalle.get(j).getHorainicio().getHours();
                a[2] = cHorarioDetalle.get(j).getHorafin().getHours();

                horario.add(a);
            }

            session.getTransaction().commit();

        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        } finally {

            session.close();
        }


        return horario;


    }
    
    public int[][] obtener_horario_docente_matriz(int iddocente) {

        Session session = HibernateUtil.getSessionFactory().openSession();
        int[][] horario = new int[14][7];

        List<ChorarioDetalle> cHorarioDetalle = new ArrayList<ChorarioDetalle>();
        List<ChorarioDisponibilidad> cHorario = null;

        try {
            session.beginTransaction();
            GenericoDAO<ChorarioDisponibilidad> cHorarioDAO = new HibernateDAO<ChorarioDisponibilidad>(ChorarioDisponibilidad.class, session);
            cHorario = cHorarioDAO.findByProperty("cdocente", iddocente, "=", " ");

            for (int i = 0; i < cHorario.size(); i++) {
                cHorarioDetalle = new ArrayList(cHorario.get(i).getChorario().getChorarioDetalles());
            }
            
            //pone toda la matriz a 0
            for(int i=0;i<14;i++)
                for(int j=0;j<7;i++)
                    horario[i][j]=0;
                    
            //la llena con 1 segun el horario
            for (int j = 0; j < cHorarioDetalle.size(); j++) {
                
                int dia = cHorarioDetalle.get(j).getDia();
                int ini = cHorarioDetalle.get(j).getHorainicio().getHours();
                int fin = cHorarioDetalle.get(j).getHorafin().getHours();
                
                for(int k=ini; k<=fin;k++)
                    horario[k-8][dia-1]=1;
            }

            session.getTransaction().commit();

        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        } finally {

            session.close();
        }


        return horario;


    }
    
    public int[][] obtener_horario_laboratorio_matriz(String Nombre) {

        Session session = HibernateUtil.getSessionFactory().openSession();
        int[][] horario = new int[14][7];
                
        List<ChorarioDetalle> cHorarioDetalle = null;
        List<ChorarioDetalle> cHorarioDetalle2 = null;
        List<ChorarioLaboratorio> cHorario = null;

        try {
            session.beginTransaction();
            GenericoDAO<ChorarioLaboratorio> cHorarioDAO = new HibernateDAO<ChorarioLaboratorio>(ChorarioLaboratorio.class, session);
            cHorario = cHorarioDAO.findByProperty("NOMLABORATORIO", Nombre, "=", "");

            for (int i = 0; i < cHorario.size(); i++) {
                cHorarioDetalle = new ArrayList(cHorario.get(i).getId().getChorario().getChorarioDetalles());    
                cHorarioDetalle2.add((ChorarioDetalle) cHorarioDetalle);
            }
            
            //pone toda la matriz a 0
            for(int i=0;i<14;i++)
                for(int j=0;j<7;i++)
                    horario[i][j]=0;
                    
            //la llena con 1 segun el horario
            for (int j = 0; j < cHorarioDetalle.size(); j++) {
                
                int dia = cHorarioDetalle.get(j).getDia();
                int ini = cHorarioDetalle.get(j).getHorainicio().getHours();
                int fin = cHorarioDetalle.get(j).getHorafin().getHours();
                
                for(int k=ini; k<=fin;k++)
                    horario[k-8][dia-1]=1;
            }

            session.getTransaction().commit();

        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        } finally {

            session.close();
        }


        return horario;

    }
      
    public Vector<int[][]> obtener_horarios_laboratorios(){
         Session session = HibernateUtil.getSessionFactory().openSession();
         List<ChorarioLaboratorio> cHorario = null;
         Vector<int [][]> horarios=new Vector<int[][]>();
         
         try{
         session.beginTransaction();
         GenericoDAO<ChorarioLaboratorio> cHorarioDAO = new HibernateDAO<ChorarioLaboratorio>(ChorarioLaboratorio.class, session);
         cHorario = cHorarioDAO.findAll("");
            for(int i=0;i<cHorario.size();i++) 
            {
                horarios.addElement(this.obtener_horario_laboratorio_matriz(cHorario.get(i).getNomlaboratorio()));
            
            }
        
        session.getTransaction().commit();

        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        } finally {

            session.close();
        }


        return horarios;
    }
    
    public List<Integer[][]> generar_horarios_curso(int[] iddocentes) {
        
        Session session = HibernateUtil.getSessionFactory().openSession();

        List<Cdocente> cDocentes = null;
        List<String[]> cPersonas = new ArrayList<String[]>();

        try {
            session.beginTransaction();
            GenericoDAO<Cdocente> cDocenteDAO = new HibernateDAO<Cdocente>(Cdocente.class, session);
            cDocentes = cDocenteDAO.findAll("");

            System.out.println("tamaño:" + cDocentes.size());

            for (int i = 0; i < cDocentes.size(); i++) {


                String[] a = new String[2];
                a[0] = cDocentes.get(i).getCpersona().getNombres() + cDocentes.get(i).getCpersona().getAppaterno();
                a[1] = (String) cDocentes.get(i).getIddocente().toString();

                cPersonas.add(a);

            }
            session.getTransaction().commit();

        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        } finally {

            session.close();
        }

        return null;
    }

    public Vector<int[]> generar_horario_curso(int iddocente) {
        
        Algoritmograsp am=new Algoritmograsp();
        
        Vector<int[][]> hrs = am.genera_matriz_interseccion(this.obtener_horario_docente_matriz(iddocente), 7, 14, this.obtener_horarios_laboratorios());

        for (int i = 0; i < hrs.size(); i++) {
            String r = "\n\n" + i;
            System.out.println(r);
            for (int k = 0; k < 14; k++) {

                String h = "";
                for (int j = 0; j < 7; j++) {
                    h = h + "  " + hrs.get(i)[k][j];

                }

                System.out.println(h);
            }


        }
        Vector<Integer> f = am.vhoras(7);

        String t = "";

        for (int i = 0; i < f.size(); i++) {
            t = t + "  " + f.get(i);

        }
        
        System.out.println("vector de horas generado");
        System.out.println(t);



        Vector<int[]> res = am.generar_vindices(f, hrs, 7, 14);




        for (int i = 0; i < res.size(); i++) {
            String r = "";
            for (int j = 0; j < res.get(i).length; j++) {
                r = r + "  " + res.get(i)[j];

            }
            System.out.println("vector de indices:");
            
            System.out.println("#indice de hora - dia - lab - tipohora - desperdicio");
        
            System.out.println(r);
        }

        Vector<int[]> sol = am.generar_horarios(res, 7, 14, f);
         System.out.println("Solucion:\n");
        
        
        for (int i = 0; i < sol.size(); i++) {
            String r = "";
            for (int j = 0; j < sol.get(i).length; j++) {
                r = r + "  " + sol.get(i)[j];

            }
            System.out.println("#indice de hora - dia - lab - tipohora - desperdicio");    
            System.out.println(r);
        }

        
        return sol;
    }
}
